/*********************************************************************************
  *Copyright (C), 2016-2022, zhangjiance Tech. Co., Ltd.
  *FileName:  https_download.h
  *Author:  JianCe.Zhang
  *Version:  V1.0
  *Date: 2023-06-14
  *Description: 
  *Function List:
  * 1. void function(void)
  * 2. 
  * 3. 
  * 4. 
  *History:
  * 1. 2022.8.28;JianCe.Zhang;Init Function 
  * 2. 
  * 3. 
  * 4. 
**********************************************************************************/

#ifndef  __https_download_H__
#define  __https_download_H__
/***************************************Includes***********************************/
#include <iostream>
#include "download_common.h"
#include <curl/curl.h>
#include <string>
#include <functional>


/***************************************Macros***********************************/
#define HTTP_RETRY_COUNT (256)

/***************************************Variables***********************************/



/***************************************Functions***********************************/
namespace zhangjiance 
{
namespace upgradeservice
{

    class HttpsDownloadTask : public DownloadTask
    {
    public:
        using SslContextCallback = std::function<CURLcode(CURL *curl, void *sslctx, void *parm)>;

        HttpsDownloadTask(const std::string url,const std::string path,bool isFsyncEnable=true) ;
        ~HttpsDownloadTask() noexcept;
        bool download() override;
        bool pause() override;
        bool resume() override;
        bool cancel() override;
        DownloadStatus getStatus() override {return m_downloadStatus;};
        int getProgress() override {return static_cast<int>(m_downloadedSize*100ll/m_fileSize);};
        std::string getDownloadUrl() override {return m_downloadUrl;};
        std::string getDownloadPath() override {return m_downloadPath;};
        long long getDownloadedSize() override {return m_downloadedSize;};
        long long getFileSize()override{return m_fileSize;};
        void setInterFace(const std::string interface) {static_cast<void>(curl_easy_setopt(m_curl, CURLOPT_INTERFACE, interface.c_str()));}
        void setDownloadUrl(const std::string &url)override{m_downloadUrl=url;};
        void setDownloadPath(const std::string &path)override {m_downloadPath=path;};
        void setOptions(std::function<void(int,DownloadStatus)> callback,long speedLimit, int connecttimeout,int downloadtimeout) override;
        void setSslVerifyPeer(bool verifyPeer);
        void setSslContext(const std::string &ClientCert,const std::string &ClientKey,const std::string &CaFile,const std::string &CaPath);
        void setSslContextCallback(std::function<CURLcode(CURL *curl, void *sslctx, void *parm)> callback,void *parm);
        long getHttpStatus(void) {return m_httpstatus;};

    private:
        CURL *m_curl = nullptr;
        FILE *m_file = nullptr;
        SslContextCallback ssl_callback = nullptr;
        std::thread * m_downloadThread = nullptr;
        int m_lastDownloadProgress = 0;
        long m_httpstatus = 200;
        bool init() override;
        void downloadThreadFunc(void);
        static int progressCallback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
        static size_t writeCallback(void *ptr, size_t size, size_t nmemb, void *userdata);
        static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm);
        HttpsDownloadTask& operator=(const HttpsDownloadTask&) = delete;
    };
}
}

#endif
/* [] END OF https_download.h */